// ****************************************************************************
// *     Filename:  EventAction.cc
// *  Description:  
// *      License:  Geant4 Software License 
// *                http://geant4.cern.ch/license/LICENSE.html
// *       Author:  Tran Hoai Nam (nam), nam@kuno-g.phys.sci.osaka-u.ac.jp
// * Organization:  Osaka University
// *      Created:  2012-09-14 15:31:31
// ****************************************************************************

#include "G4Event.hh"
#include "G4HCofThisEvent.hh"
#include "G4SDManager.hh"

#include "EventAction.hh"
#include "MyHit.hh"
#include "HistoManager.hh"
#include "PrimaryGeneratorAction.hh"
#include <string>

EventAction::EventAction() 
{
	fpSDMan  = G4SDManager::GetSDMpointer();
}

EventAction::EventAction(PrimaryGeneratorAction *priGen) 
{
	fpPriGen = priGen;
	fpSDMan  = G4SDManager::GetSDMpointer();
}

EventAction::EventAction(HistoManager* histo, PrimaryGeneratorAction *priGen) 
{
	fpHistoMan = histo;
	fpPriGen= priGen;
	fpSDMan  = G4SDManager::GetSDMpointer();
}

EventAction::~EventAction() {;}

void EventAction::BeginOfEventAction(const G4Event* ) 
{;}

void EventAction::EndOfEventAction(const G4Event* event)
{
	fpEvt = new TEvent();
	unsigned long int evtid = event->GetEventID();
	fpEvt->SetEvtId(evtid);
	G4cout<<evtid<<G4endl;
	//G4cout<<": "<<fpPriGen->GetPrimaryEnergy()/MeV<<G4endl;
	fpEvt->AddEdep(fpPriGen->GetPrimaryEnergy()/MeV); //fEdep[0]
	ReadTracker(event,"aSD1",0,0); //fEdep[1]
	ReadTracker(event,"aSD2",0,1); //fEdep[2]
	fpHistoMan->WriteEvt(fpEvt);
	fpHistoMan->FillTree();
	//if (evtid%1000 == 1) fpHistoMan->AutoSave();
}

void EventAction::ProcessTrackerHit(MyHit *aHit, uint8_t id) 
{
	if(aHit->IsPriStopped())
	{
		//aHit->Print();
		TTrackerHit aTrkHit;
		aTrkHit.SetHitType(TTrackerHit::PrimaryStopped);
		aTrkHit.SetDetID(id);
		aTrkHit.SetTime(aHit->GetStopTime()/ns);
		aTrkHit.SetPName(aHit->GetName());
		aTrkHit.SetPCode(aHit->GetPID());
		G4ThreeVector aPos = aHit->GetStopPoint();
		aTrkHit.SetPos(aPos.x()/um,aPos.y()/um,aPos.z()/um);
		//fpEvt->SetPriStoppedFlag(); // This is for target only
		fpEvt->AddHit(aTrkHit);

		//double pos[3];
		//aTrkHit.GetPos(pos);
		//G4cout<<"pos: "<<pos[0]<<", "<<pos[1]<<", "<<pos[2]<<"\n";
		//G4cout<<"Showhit: \n";
		//aTrkHit.ShowHit();
	}	
	if (aHit->GetDirection() == 1)
	{
		TTrackerHit aTrkHit(id);
		aTrkHit.SetHitType(TTrackerHit::ParticleEntered);
		aTrkHit.SetTime(aHit->GetTime()/ns);
		aTrkHit.SetKE(aHit->GetKE()/keV);
		aTrkHit.SetPCode(aHit->GetPID());
		aTrkHit.SetPName(aHit->GetName());
		aTrkHit.SetTrackID(aHit->GetTrackID());
		G4ThreeVector aPos = aHit->GetPos();
		aTrkHit.SetPos(aPos.x()/um,aPos.y()/um,aPos.z()/um);
		fpEvt->AddHit(aTrkHit);
		//aTrkHit.ShowHit();
	}
	else if (aHit->GetDirection() == -1)
	{
		TTrackerHit aTrkHit(id);
		aTrkHit.SetHitType(TTrackerHit::ParticleExited);
		aTrkHit.SetTime(aHit->GetTime()/ns);
		aTrkHit.SetKE(aHit->GetKE()/keV);
		aTrkHit.SetPCode(aHit->GetPID());
		aTrkHit.SetPName(aHit->GetName());
		aTrkHit.SetTrackID(aHit->GetTrackID());
		G4ThreeVector aPos = aHit->GetPos();
		aTrkHit.SetPos(aPos.x()/um,aPos.y()/um,aPos.z()/um);
		fpEvt->AddHit(aTrkHit);
		//aTrkHit.ShowHit();
	}
}
void EventAction::ReadTracker(const G4Event *event, G4String detName,
		G4int detCopyNo, uint8_t id) 
{
	G4int hitsCollID = fpSDMan->GetCollectionID(detName);
	//G4cout<<"det: "<<detName<<G4endl;
	if(hitsCollID >= 0)
	{
		G4HCofThisEvent *aHCE = event->GetHCofThisEvent();
		MyHitsCollection* hitsCollection= 
			dynamic_cast<MyHitsCollection*>(aHCE->GetHC(hitsCollID));
		G4int NoOfHits = hitsCollection->GetSize();
		//Scan all hits
		G4double Edep = 0.;
		for (int i=0;i<NoOfHits;i++)
		{
			MyHit* aHit = (*hitsCollection)[i];
			if (aHit->GetCopyNo()==detCopyNo)
			{
				switch(aHit->GetHitType())
				{
					case MyHit::CaloHit:
						Edep += aHit->Getedep();
						break;
					case MyHit::TrackerHit:
						ProcessTrackerHit(aHit,id);
						break;
					default:
						break;
				}
			}
		}
		fpEvt->AddEdep(Edep/keV);
		//G4cout<<"Edep: "<<Edep/keV<<G4endl;
	}
}
